/*
 * Created on 2005-2-17
 *
 */
package bma.common.langutil.core;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author 关中
 * @since 1.0 (imported from BMA.ESP Project)
 * 
 */
public class NameValueCollection<V> {

	private List<NameValue<V>> values;

	private NameValueCollection<V> defaults;

	public NameValueCollection() {
		values = new ArrayList<NameValue<V>>();
	}

	public NameValueCollection(List<NameValue<V>> attr) {
		values = attr;
	}

	public void setDefaults(NameValueCollection<V> defaults) {
		this.defaults = defaults;
	}

	public NameValueCollection(int sz) {
		values = new ArrayList<NameValue<V>>(sz);
	}

	public void clear() {
		values.clear();
	}

	private static boolean same(String name, String key) {
		if (name == null)
			return key == null;
		return name.equals(key);
	}

	public boolean containKey(String key) {
		for (NameValue<V> nv : values) {
			if (same(nv.getName(), key)) {
				return true;
			}
		}
		return defaults == null ? false : defaults.containKey(key);
	}

	public boolean containValue(V value) {
		for (NameValue<V> nv : values) {
			if (value != null) {
				if (value.equals(nv.getValue())) {
					return true;
				}
			} else {
				if (nv.getValue() == null)
					return true;
			}
		}
		return defaults == null ? false : defaults.containValue(value);
	}

	public V get(String key) {
		for (NameValue<V> nv : values) {
			if (same(nv.getName(), key)) {
				return nv.getValue();
			}
		}
		return defaults == null ? null : defaults.get(key);
	}

	public NameValue<V> getItem(String key) {
		for (NameValue<V> nv : values) {
			if (same(nv.getName(), key)) {
				return nv;
			}
		}
		return defaults == null ? null : defaults.getItem(key);
	}

	public NameValue<V> getItemByValue(V v) {
		for (NameValue<V> nv : values) {
			if (ObjectUtil.equals(nv.getValue(), v)) {
				return nv;
			}
		}
		return defaults == null ? null : defaults.getItemByValue(v);
	}

	public void set(String key, V value) {
		for (NameValue<V> nv : values) {
			if (same(nv.getName(), key)) {
				nv.setValue(value);
				return;
			}
		}
		add(key, value);
	}

	public void add(String key, V value) {
		NameValue<V> nv = new NameValue<V>(key, value);
		values.add(nv);
	}

	public void remove(String key) {
		Iterator<NameValue<V>> it = values.iterator();
		while (it.hasNext()) {
			NameValue<V> nv = it.next();
			if (same(nv.getName(), key)) {
				it.remove();
			}
		}
	}

	public void removeByValue(Object value) {
		Iterator<NameValue<V>> it = values.iterator();
		while (it.hasNext()) {
			NameValue<V> nv = it.next();
			if (ObjectUtil.equals(nv.getValue(), value)) {
				it.remove();
			}
		}
	}

	public void removeByItem(NameValue<V> item) {
		Iterator<NameValue<V>> it = values.iterator();
		while (it.hasNext()) {
			NameValue<V> nv = it.next();
			if (ObjectUtil.equals(nv, item)) {
				it.remove();
			}
		}
	}

	public String[] listAllName() {

		ArrayList<String> r = new ArrayList<String>(values.size());

		for (NameValue<V> nv : values) {
			r.add(nv.getName());
		}
		return r.toArray(new String[r.size()]);
	}

	public int size() {
		return this.values.size();
	}

	public boolean isEmpty() {
		return size() == 0;
	}

	public List<NameValue<V>> getValues() {
		return values;
	}

	public void addAll(NameValueCollection<V> list) {
		for (NameValue<V> nv : list.values) {
			add(nv.getName(), nv.getValue());
		}
	}

}